/*
 * cpu.h
 *
 *  Created on: Feb 4, 2012
 *      Author: Craig Markham and James Marquardt
 *              Class:  TCSS 371
 *              Assignment:
 */

#ifndef CPU_H_
#define CPU_H_
#endif /* CPU_H_ */

#include "alu.h"
//#include "debugMonitor.h"

#define RUN     10
#define STEP    11

#define GO      1
#define STOP    0

//Macros for different opcodes in the IR.
 
#define ALU_1 0x9
#define ALU_2 0x8
#define ALU_3 0xA
#define LDI 0x1
#define LDA 0x2
#define LDB 0x3
#define LDW 0x4
#define STB 0x5
#define STW 0x6
#define PUSHPOP 0x7
#define BRLOCAL 0x10
#define BRREG 0x11
#define BRCLOCAL 0x12
#define BRCREG 0x13
#define JSR 0x14
#define JSRC 0x15
#define TRAP 0x16
#define RET 0x17
#define IO 0x18
#define EIDI 0x19
#define HALT 0x1A
#define NOP 0x1B
#define LDOS 0x1C
#define LDRO 0x1D

/*
 * ADT - CPU
 * Data Type Description:
 * Using the ADTs from Phase I.
 */

typedef struct {
    Register status;
    Register data;
} KEYBOARD;

typedef struct {
    Register status;
    Register data;
} MONITOR;

typedef struct {
        RegisterFilePtr registerFile;   // internal register file
        MemoryModulePtr mainMemory;     // external memory - this simulates the bus!
        ALU * alu_ptr;                  // internal ALU
        KEYBOARD * keyboard_ptr;		//
        MONITOR * monitor_ptr;			//
        int macroState;         // one or more integers contain the control state (e.g. fetch, etc)
        int microState;         // needed for switch inside of switch!
        Register SW, PC, IR, MDR, MAR;  // data path registers
        int stateMachineStatus;
        int debugState;         // used to inform the CPU

} CPU;

//Initializes the CPU
CPU * initialize(CPU * cpu_ptr);

KEYBOARD * initKeyboard(KEYBOARD * );

MONITOR * initMonitor(MONITOR * );
//Prototypes for CPU functions.

void cpu_run(CPU *);

int fetch(CPU * );

void decode(CPU *);

void cpu_runALU(CPU * , int );

void cpu_runLDI(CPU * );

void cpu_runLDA(CPU * );

void cpu_runLDB(CPU * );

void cpu_runLDW(CPU * );

void cpu_runSTB(CPU * );

void cpu_runSTW(CPU * );

void cpu_runPUSHPOP(CPU * );

void cpu_runBRLOCAL(CPU * );

void cpu_runBRREG(CPU * );

void cpu_runBRCLOCAL(CPU * );

void cpu_runBRCREG(CPU * );

void cpu_runMOV(CPU * );

void cpu_runPUSHB(CPU * );

void cpu_runPOPB(CPU * );

void cpu_runPUSHW(CPU * );

void cpu_runPOPW(CPU * );

void cpu_runJSR(CPU * );

void cpu_runJSRC(CPU * );

void cpu_fetchOperands(CPU * );

void cpu_runTRAP(CPU * );

void cpu_runRET(CPU * );

void cpu_runIO(CPU *);

void cpu_runEIDI(CPU * );

void cpu_runLDOS(CPU * );

void cpu_runLDRO(CPU * );

void cpu_runIn(CPU *, int);

void cpu_runOut(CPU *, int);

void cpu_runKeyboardIn(CPU *);

void cpu_runMonitorOut(CPU *);

